package com.gidgabs.modules.api.controller;


import com.aliyuncs.exceptions.ClientException;
import com.gidgabs.common.annotation.AuthIgnoreApi;
import com.gidgabs.common.annotation.LoginUserApi;
import com.gidgabs.common.utils.R;
import com.gidgabs.common.utils.ReturnJson;
import com.gidgabs.common.validator.Assert;
import com.gidgabs.modules.api.service.TbTokenService;
import com.gidgabs.modules.api.service.TbUserService;
import com.gidgabs.modules.entity.TbUser;
import com.gidgabs.utils.FastDFSClientWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * register
 */
@RestController
@RequestMapping("/api/user")
@Api("注册")
public class ApiRegisterController {
    @Autowired
    private TbUserService userService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private TbTokenService tokenService;
    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private FastDFSClientWrapper fastDFSClientWrapper;


    @Value("${spring.mail.username}")
    private String username;
    private static final Logger LOGGER= LoggerFactory.getLogger(ApiRegisterController.class);


    /**
     * 注册
     * @param mobile 手机号
     * @param password 密码
     * @param code 验证码
     * @param choose_type 账号类型
     * @return
     */
    /*@AuthIgnoreApi
    @PostMapping("/register")
    public R register(String mobile, String password, String code,int choose_type){
        Assert.isBlank(mobile, "phone number is empty");
        Assert.isBlank(password, "password is empty");
        Assert.isBlank(code, "verification code is empty");
        //判断验证码是否正确
        String rcode = redisTemplate.opsForValue().get(mobile);
        if (rcode == null) {
            return R.error("verification code has expired");
        }
        if (rcode.equals(code)) {
            if (userService.queryByMobile(mobile) == null) {
                TbUser tbUser = new TbUser();
                tbUser.setPassword(DigestUtils.sha256Hex(password));
                tbUser.setMobile(mobile);
                tbUser.setDeleteType(0);
                tbUser.setUserCode(UUID.randomUUID().toString());
                tbUser.setCreateTime(new Date());
                tbUser.setChooseType(choose_type);
                //持久化数据
                userService.save(tbUser);
                return R.ok();
            } else {
                return R.error("the phone number has been registered");
            }
        } else {
            return R.error("verification code is error");
        }
    }*/
    @ApiOperation(value = "注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "email",value = "电子邮箱",dataType = "string",paramType = "form"),
            @ApiImplicitParam(name = "password",value = "密码",dataType = "string",paramType = "form"),
            @ApiImplicitParam(name = "chooseType",value = "1商户,2普通用户",dataType = "int",paramType = "form"),
            @ApiImplicitParam(name = "birth",value = "yyyy-MM-dd",dataType = "string",paramType = "form"),
            @ApiImplicitParam(name = "gender",value = "1商户,2普通用户",dataType = "int",paramType = "form"),
            @ApiImplicitParam(name = "occupation",value = "职业",dataType = "string",paramType = "form"),
            @ApiImplicitParam(name = "code",value = "验证码",dataType = "string",paramType = "form")
    })
    @AuthIgnoreApi
    @PostMapping("/register")
    public ReturnJson register(String email, String password, String code, Integer chooseType, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birth, Integer gender, String occupation){
        Assert.isBlank(email, "phone number is empty");
        Assert.isBlank(password, "password is empty");
        Assert.isBlank(code, "verification code is empty");
        if (chooseType==null){
            chooseType=2;
        }
        //判断验证码是否正确
        String rcode = redisTemplate.opsForValue().get(email);
        if (rcode == null) {
            return ReturnJson.fail("verification code has expired");
        }
        if (rcode.equals(code)) {
            if (userService.queryByEmail(email) == null) {
                TbUser tbUser = new TbUser(password,email,chooseType,birth,gender,occupation);
                //持久化数据
                userService.save(tbUser);
                return ReturnJson.success("注册成功");
            } else {
                return ReturnJson.fail("the email number has been registered");
            }
        } else {
            return ReturnJson.fail("verification code is error");
        }
    }

    private static int captchaExpires = 1800; //超时时间30分钟

    /**
     * 忘记登录密码并修改登录密码
     * @param mobile 手机删除
     * @param password 密码 
     * @param code 验证码
     * @return
     */
   /* @AuthIgnoreApi
    @PostMapping("/updatePassword")
    public R forgetAndUpdate(String mobile, String password, String code){
        Assert.isBlank(mobile, "phone number is empty");
        Assert.isBlank(password, "password is empty");
        Assert.isBlank(code, "verification code is empty");
        //判断验证码是否正确
        String rcode = redisTemplate.opsForValue().get(mobile);
        if (rcode == null) {
            return R.error("verification code has expired");
        }
        if (rcode.equals(code)){
            TbUser tbUser = userService.queryByMobile(mobile);
            if (tbUser == null) {
                return R.error("the phone number is not registered");
            }
            tbUser.setPassword(DigestUtils.sha256Hex(password));
            userService.updatePsByUserId(tbUser);
            return R.ok().put("data",tbUser);
        }else {
            return R.error("verification code is error");
        }

    }*/

    @ApiOperation(value = "忘记密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "email",value = "电子邮箱",dataType = "string",paramType = "form"),
            @ApiImplicitParam(name = "password",value = "密码",dataType = "string",paramType = "form"),
            @ApiImplicitParam(name = "code",value = "验证码",dataType = "string",paramType = "form")
    })
    @AuthIgnoreApi
    @PostMapping("/updatePassword")
    public ReturnJson forgetAndUpdate(String email, String password, String code){
        Assert.isBlank(email, "email number is empty");
        Assert.isBlank(password, "password is empty");
        Assert.isBlank(code, "verification code is empty");
        //判断验证码是否正确
        String rcode = redisTemplate.opsForValue().get(email);
        if (rcode == null) {
            return ReturnJson.fail("verification code has expired");
        }
        if (rcode.equals(code)){
            TbUser tbUser = userService.queryByEmail(email);
            if (tbUser == null) {
                return ReturnJson.fail("the email number is not registered");
            }
            tbUser.setPassword(DigestUtils.sha256Hex(password));
            userService.updatePsByUserId(tbUser);
            return ReturnJson.success("修改成功",tbUser);
        }else {
            return ReturnJson.fail("verification code is error");
        }

    }

    /**
     * 修改登录密码
     * @return
     */
    @PostMapping("/userUpdatePassWord")
    public R userUpdatePassWord(@LoginUserApi TbUser tbUser, String password, String code){
        Assert.isBlank(password, "password is empty");
        Assert.isBlank(code, "code is empty");
        if(tbUser == null){
            //设置换回编码为501 登录需要登录或者登录失效
            return  R.error(501,"logon failure");
        }
        if(tbUser.getMobile() == null || tbUser.getMobile().equals("")){
            //微信授权登录没有手机号码
            return  R.error("need set phone number");
        }
        //判断验证码是否正确
        String rcode = redisTemplate.opsForValue().get(tbUser.getMobile());
        if (rcode == null) {
            return R.error("verification code has expired");
        }
        if (rcode.equals(code)){
            tbUser.setPassword(DigestUtils.sha256Hex(password));
            userService.updatePsByUserId(tbUser);
            return R.ok().put("data",tbUser);
        }else {
            return R.error("verification code is error");
        }
    }


    /**
     * 判断是否有支付密码
     * @param tbUser
     * @return
     */
    @PostMapping("/isNotPayPassWord")
    public R isNotPayPassWord(@LoginUserApi TbUser tbUser){
        if(tbUser == null){
            //设置换回编码为501 登录需要登录或者登录失效
            return  R.error(501,"用户登录失效");
        }
        if(tbUser.getPaypassword() == null){
            return R.error(503,"没有设置支付密码");
        }
        return R.error(504,"有密码");
    }


    /**
     * 设置支付密码 or 修改支付密码
     * @param tbUser
     * @param payPassWord
     * @param code
     * @return
     */
    @PostMapping("/updatePayPassWord")
    public R updatePayPassWord(@LoginUserApi TbUser tbUser,String payPassWord, String code){
        if(tbUser == null){
            //设置换回编码为501 登录需要登录或者登录失效
            return  R.error(501,"用户登录失效");
        }
        if(tbUser.getMobile() == null || tbUser.getMobile().equals("")){
            //微信授权登录没有手机号码
            return  R.error("没有设置手机号");
        }
        Assert.isBlank(payPassWord, "密码不能为空");
        //有验证码代表修改密码 没有验证码 是初次设置密码
        if(code != null && !code.equals("")){
            //判断验证码是否正确
            String rcode = redisTemplate.opsForValue().get(tbUser.getMobile());
            if (rcode == null) {
                return R.error("验证码过期");
            }
            if (rcode.equals(code)){
                tbUser.setPaypassword(DigestUtils.sha256Hex(payPassWord));
                userService.updatePsByUserId(tbUser);
                return R.ok();
            }else {
                return R.error("验证码错误");
            }
        }else{
            tbUser.setPaypassword(DigestUtils.sha256Hex(payPassWord));
            userService.updatePsByUserId(tbUser);
            return R.ok();
        }
    }

    /**
     * 获取验证码
     */
    /*@AuthIgnoreApi
    @GetMapping("/getCode")
    public R getCode(String phone) throws ClientException {
        Assert.isBlank(phone, "phone number is empty");
        //生成验证码
        String code = String.valueOf(new Random().nextInt(99999));
        //将验证码以<key,value>形式缓存到redis
        redisTemplate.opsForValue().set(phone, code);
        //设置过期时间
        redisTemplate.expire(phone, captchaExpires, TimeUnit.SECONDS);
        //调用第三方短信接口
        SendSmsResponse response = SmsDemo.sendSms(phone, Integer.valueOf(code));
        if ("isv.BUSINESS_LIMIT_CONTROL".equals(response.getCode())) {
            return R.error("一分钟内只能发一次");
        } else {
            return R.ok().put("data", response);
        }
    }*/

    @ApiOperation(value = "获取验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "email",value = "电子邮箱",dataType = "string",paramType = "query")
    })
    @AuthIgnoreApi
    @GetMapping("/getCode")
    public ReturnJson getCode(String email) throws ClientException {

        Assert.isBlank(email, "email number is empty");
        //生成验证码
        String code = String.valueOf(new Random().nextInt(99999));
        LOGGER.info("生成的验证码为: "+code);
        //将验证码以<key,value>形式缓存到redis
        redisTemplate.opsForValue().set(email, code);
        //设置过期时间
        redisTemplate.expire(email, captchaExpires, TimeUnit.SECONDS);
        //调用第三方短信接口
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(username);
        simpleMailMessage.setTo(email);//接收邮件的邮箱
        simpleMailMessage.setSubject("Verification code from gibgiabs");
        simpleMailMessage.setText("FROM GIBGIABS Verification code:"+code);
        //Verification code FROM GIBGIABS

        mailSender.send(simpleMailMessage);
        return ReturnJson.success("验证码发送成功");
    }
}

